package hust.cs.javacourse.search.index.impl;

import hust.cs.javacourse.search.index.AbstractPosting;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.*;

public class Posting extends AbstractPosting {
    /**
     * 缺省构造方法
     */
    public Posting() {
        super();
    }

    /**
     * 构造方法
     * @param docId：包含单词的文档ID
     * @param freq：单词在文档中出现的次数
     * @param positions：单词在文档中出现的次数
     */
    public Posting(int docId, int freq, List<Integer> positions) {
        super(docId, freq, positions);
    }

    /**
     * 比较两个posting是否相等
     * @param obj ：要比较的另外一个Posting
     * @return ：如果相等返回true，否则返回false
     */
    @Override
    public boolean equals(Object obj) {
        if(obj instanceof Posting) {
            Posting p = (Posting) obj;
            boolean flag = false;
            if(this.docId != p.docId || this.freq != p.freq)
                return false;
            else if(this.positions.size() != p.positions.size())
                return false;
            else {
                for(int i = 0;i < p.positions.size();i++) {
                    if(!this.positions.contains(p.positions.get(i)))
                        return false;
                }
                return true;
            }
        }
        return false;
    }

    /**
     * 返回Posting的字符串表示
     * @return ：字符串
     */
    @Override
    public String toString() {
        String info = "{docId: " + docId +
                ", freq: " + freq +
                ", position: " + positions + "}";
        return info;
    }

    /**
     * 获取包含该单词的文档Id
     * @return ：文档Id
     */
    @Override
    public int getDocId() {
        return this.docId;
    }

    /**
     * 设置包含该单词的文档Id
     * @param docId：包含单词的文档id
     */
    @Override
    public void setDocId(int docId) {
        this.docId = docId;
    }

    /**
     * 返回单词在文档中出现的次数
     * @return ：单词出现的次数
     */
    @Override
    public int getFreq() {
        return this.freq;
    }

    /**
     * 设置单词在文档中出现的次数
     * @param freq:单词在文档里出现的次数
     */
    @Override
    public void setFreq(int freq) {
        this.freq = freq;
    }

    /**
     * 返回单词出现的位置列表
     * @return ：单词的位置列表
     */
    @Override
    public List<Integer> getPositions() {
        return this.positions;
    }

    /**
     * 设置单词出现的位置列表
     * @param positions：单词在文档里出现的位置列表
     */
    @Override
    public void setPositions(List<Integer> positions) {
        this.positions = positions;
    }

    /**
     * 比较两个Posting的大小（根据docId）
     * @param o： 另一个Posting对象
     * @return ：两个Posting的docId的差值
     */
    @Override
    public int compareTo(AbstractPosting o) {
        return this.docId - o.getDocId();
    }

    /**
     * 对Posting中的position排序（从小到大）
     */
    @Override
    public void sort() {
        Collections.sort(this.positions);
    }

    /**
     * 将对象序列化到二进制文件
     * @param out :输出流对象
     */
    @Override
    public void writeObject(ObjectOutputStream out) {
        try {
            out.writeObject(this.docId);
            out.writeObject(this.freq);
            out.writeObject(this.positions);
            //out.close();
        } catch (IOException i) {
            i.printStackTrace();
        }
    }

    /**
     * 从二进制文件中反序列化到输入流
     * @param in ：输入流对象
     */
    @Override
    public void readObject(ObjectInputStream in) {
        try {
            this.docId = (int) (in.readObject());
            this.freq = (int) (in.readObject());
            this.positions = (List) (in.readObject());
            //in.close();
        } catch (IOException i) {
            i.printStackTrace();
        } catch(ClassNotFoundException c)
        {
            //System.out.println("Employee class not found");
            c.printStackTrace();
        }
    }
}
